/**
 * 
 */
package mm.back.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import mm.back.DetalleVentaDTO;
import mm.back.dao.ProductoDAO;
import mm.back.dao.VendedorDAO;
import mm.back.dao.VentasDAO;
import mm.back.entity.DetalleVenta;
import mm.back.entity.Producto;
import mm.back.entity.Vendedor;
import mm.back.entity.Venta;
import mm.back.filtros.VentasFiltro;
import mm.back.service.MMAbstractService;
import mm.back.service.VentasService;
import mm.back.validations.VentaValidator;
import mm.exceptions.MMGenericException;
import mm.exceptions.MMInvalidIDException;

/**
 * @author PUSDERKIS
 *
 */
public class VentasServiceImpl extends MMAbstractService implements VentasService {

	
	private VentasDAO ventasDAO;
	
	private VendedorDAO vendedorDAO;
	
	private ProductoDAO productoDAO;
	
	/** 
	 * @see mm.back.service.VentasService#registrarVenta(mm.back.entity.Venta)
	 */
	public void registrarVenta(Venta venta) throws MMGenericException {
		
		if (venta.getVendedor() != null){
			Vendedor vendedorTmp = vendedorDAO.getVendedor(venta.getVendedor().getId());
			venta.setVendedor(vendedorTmp);
		}
		
		VentaValidator.ValidarVenta(venta);
		Producto tmpProd = null;
		for (DetalleVenta dv : venta.getDetalleVenta()){
			tmpProd = productoDAO.restarStock(dv.getProducto().getId(), dv.getCantidad());
			dv.setProducto(tmpProd);
		}
		tmpProd = null;
		
		ventasDAO.saveVenta(venta);
		
	}

	/**
	 * @return the vendedorDAO
	 */
	public VendedorDAO getVendedorDAO() {
		return vendedorDAO;
	}

	/**
	 * @param vendedorDAO the vendedorDAO to set
	 */
	public void setVendedorDAO(VendedorDAO vendedorDAO) {
		this.vendedorDAO = vendedorDAO;
	}

	/**
	 * @return the productoDAO
	 */
	public ProductoDAO getProductoDAO() {
		return productoDAO;
	}

	/**
	 * @param productoDAO the productoDAO to set
	 */
	public void setProductoDAO(ProductoDAO productoDAO) {
		this.productoDAO = productoDAO;
	}

	/**
	 * @param ventasDAO the ventasDAO to set
	 */
	public void setVentasDAO(VentasDAO ventasDAO) {
		this.ventasDAO = ventasDAO;
	}

	/** 
	 * @see mm.back.service.VentasService#buscarVentas(mm.back.filtros.VentasFiltro)
	 */
	public List<Venta> buscarVentas(VentasFiltro filtro)
			throws MMGenericException {
		
		return ventasDAO.buscarVentas(filtro);
	}

	/** 
	 * @see mm.back.service.VentasService#buscarVenta(java.lang.Long)
	 */
	public Venta buscarVenta(Long idVenta) throws MMGenericException {
		if (idVenta == null || idVenta <= 0) {
			logger.error("No se recibio el número de venta para acceder al detalle. Id venta: "+idVenta);
			throw new MMInvalidIDException("No se recibio el número de venta para acceder al detalle. Id venta: "+idVenta);
		}
		
		return ventasDAO.buscarVenta(idVenta);
	}

	/**
	 * @see mm.back.service.VentasService#buscarDetalleVentas(java.lang.Long)
	 */
	public List<DetalleVenta> buscarDetalleVentas(Long idVenta)
			throws MMGenericException {
		if (logger.isDebugEnabled()){
			logger.debug("Se recuperara el listado de ventas para la venta número: "+idVenta);
		}
		Venta v = ventasDAO.buscarVenta(idVenta);
		List<DetalleVenta> dvList = new ArrayList<DetalleVenta>(v.getDetalleVenta());
		return dvList;
	}

	/**
	 * @see mm.back.service.VentasService#registrarDevolucion(java.lang.Long, java.util.List)
	 */
	public void registrarDevolucion(Long idVenta,
			List<DetalleVentaDTO> detalleVentaDTO) throws MMGenericException {
		
		
		if (logger.isDebugEnabled()){
			logger.debug("Se registrara una devolución de productos para la venta: "+idVenta);
		}
		Venta v = ventasDAO.buscarVenta(idVenta);
		if (detalleVentaDTO != null){
			BigDecimal cantidadADescontar = new BigDecimal(0);
			for(DetalleVentaDTO dto : detalleVentaDTO){
				
				if (BigDecimal.ZERO.compareTo(dto.getDevolucion()) < 0 ){
					
					BigDecimal cant = dto.getDetalleVenta().getCantidad().subtract(dto.getDevolucion());
					
					dto.getDetalleVenta().setCantidad(cant);
					
					Producto p = productoDAO.getProducto(dto.getDetalleVenta().getProducto().getId());
					
					p.setStock(p.getStock().add(dto.getDevolucion()));
					
					productoDAO.saveProducto(p);
					
					cantidadADescontar = cantidadADescontar.add(dto.getDevolucion().multiply(dto.getDetalleVenta().getPrecioVenta()));
					
				}
					
				if (BigDecimal.ZERO.compareTo(dto.getDetalleVenta().getCantidad()) == 0){
					v.getDetalleVenta().remove(dto.getDetalleVenta());
//					ventasDAO.deleteDetalleVenta(dto.getDetalleVenta().getId());
				} else {
					ventasDAO.updateDetalle(dto.getDetalleVenta());
				}
				
			}
			
			BigDecimal total = v.getTotal().subtract(cantidadADescontar);
			
			v.setTotal(total);
			
			ventasDAO.saveVenta(v);
			
			if (logger.isDebugEnabled()){
				logger.debug("Se registro con exito la devolución correspondiente a la venta " + idVenta + " por un total de " + cantidadADescontar);
			}
		}
		
		
	}


}
